package dwei.ui
{
	import dwei.core.timer.TimerMgr;
	import dwei.core.timer.TimerVO;
	
	import flash.display.DisplayObject;
	import flash.display.Stage;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	public class UIMgr
	{
//============================================================================
//PROPERTY
//============================================================================
		private static var _uiStage:UIStage;
		private static const _size:UISize = new UISize();
		private static const _rect:Rectangle = new Rectangle();
		private static const _containers:Array = [];
		private static const _layerContainerMap:Object = {};
		private static const _uidDelayTimerMap:Object = {};
//============================================================================
//PUBILC
//============================================================================
		/**
		 * 初始化UI框架
		 * @param stage
		 * 
		 */		
		public static function initialze(uiStage:UIStage):void
		{
			_uiStage = uiStage;
		}
		/**
		 * 添加UISprite
		 * @param ui
		 * 
		 */		
		public static function addUI(ui:UISprite):void
		{
			if (!(ui is DisplayObject)) return;
			var container:UISprite = _layerContainerMap[ui.layer];
			if (container == null)
			{
				container = new UISprite();
				container.layer = ui.layer;
				_containers.push(container);
				_layerContainerMap[ui.layer] = container;
				_uiStage.addChild(container);
				
				container.width = _rect.width;
				container.height = _rect.height;
				container.x = _rect.x;
				container.y = _rect.y;
				validateContainerDepth();
			}
			var loop:DisplayObject;
			var length:int = container.numChildren;
			if (ui.exclude && length != 0)
			{
				for (var index:int = length - 1;index >= 0;index--)
				{
					loop = container.getChildAt(index);
					if ((loop != ui) && (loop is UISprite)) container.removeChildAt(index);
				}
			}
			if (container.contains(ui as DisplayObject))
			{
				container.setChildIndex(ui as DisplayObject, container.numChildren - 1);
				if (ui.delay != 0)
				{
					TimerMgr.removeTimer(_uidDelayTimerMap[ui.uid]);
					_uidDelayTimerMap[ui.uid] = TimerMgr.addTimer(ui.delay, uiDelayed_cb, ui);
				}
			}
			else
			{
				container.addChild(ui as DisplayObject);
				if (ui.delay != 0) _uidDelayTimerMap[ui.uid] = TimerMgr.addTimer(ui.delay, uiDelayed_cb, ui);
			}
		}
		/**
		 * 删除指定UISprite
		 * @param ui
		 * 
		 */		
		public static function removeUI(ui:UISprite):void
		{
			if (!(ui is DisplayObject)) return;
			var container:UISprite = _layerContainerMap[ui.layer];
			if (container == null || !container.contains(ui as DisplayObject)) return;
			if (ui.uid in _uidDelayTimerMap)
			{
				TimerMgr.removeTimer(_uidDelayTimerMap[ui.uid]);
				delete _uidDelayTimerMap[ui.uid];
			}
			container.removeChild(ui as DisplayObject);
			if (container.numChildren > 0) return;
			_uiStage.removeChild(container);
			delete _layerContainerMap[ui.layer];
			_containers.splice(_containers.indexOf(container), 1);
		}
		/**
		 * 判断指定UISprite是否已存在
		 * @param ui
		 * @return 
		 * 
		 */		
		public static function hasUI(ui:UISprite):Boolean
		{
			if (ui == null) return false;
			var container:UISprite = _layerContainerMap[ui.layer];
			if (container == null) return false;
			return container.contains(ui as DisplayObject);
		}
		/**
		 * 获取指定层的所有UISprite
		 * @param layer
		 * @return 
		 * 
		 */		
		public static function getChildrenInLayer(layer:uint):Array
		{
			var children:Array = [];
			var container:UISprite = _layerContainerMap[layer];
			if (container == null) return children;
			var length:int = container.numChildren;
			for (var index:int = 0;index < length;index++)
			{
				children.push(container.getChildAt(index));
			}
			return children;
		}
		public static function layout(ui:IUI, containerRect:Rectangle):void
		{
			if (ui == null) return;
			
			var x:int = ui.x;
			switch (ui.horizontalAlign)
			{
				case UIAlign.LEFT:
					x = 0;
					break;
				case UIAlign.CENTER:
					x = Math.max(0, (containerRect.width - ui.width) / 2);
					break;
				case UIAlign.RIGHT:
					x = containerRect.width - ui.width;
					break;
			}
			var y:int = ui.y;
			switch (ui.verticalAlign)
			{
				case UIAlign.TOP:
					y = 0;
					break;
				case UIAlign.MIDDLE:
					y = Math.max(0, (containerRect.height- ui.height) / 2);
					break;
				case UIAlign.BOTTOM:
					y = containerRect.height - ui.height;
					break;
			}
			ui.move(x, y);
		}
		/**
		 * 计算布局的左上角坐标
		 * @param rectTarget
		 * @param rectContainer
		 * @param hAlign
		 * @param vAlign
		 * @return 
		 * 
		 */		
		public static function layout2(rectTarget:Rectangle, rectContainer:Rectangle, hAlign:String, vAlign:String):Point
		{
			var point:Point = new Point(rectTarget.x, rectTarget.y);
			switch (hAlign)
			{
				case UIAlign.LEFT:
					point.x = 0;
					break;
				case UIAlign.CENTER:
					point.x = Math.max(0, (rectContainer.width - rectTarget.width) / 2);
					break;
				case UIAlign.RIGHT:
					point.x = rectContainer.width - rectTarget.width;
					break;
			}
			switch (vAlign)
			{
				case UIAlign.TOP:
					point.y = 0;
					break;
				case UIAlign.MIDDLE:
					point.y = Math.max(0, (rectContainer.height- rectTarget.height) / 2);
					break;
				case UIAlign.BOTTOM:
					point.y = rectContainer.height - rectTarget.height;
					break;
			}
			return point;
		}
//============================================================================
//PRIVATE
//============================================================================
//		private static function validateAppSize():void
//		{
//			_uiStage.width = _uiStage.stage.stageWidth;
//			_uiStage.height = _uiStage.stage.stageHeight;
//			var rectOld:Rectangle = _rect.clone();
//			
//			_rect.width = Math.max(_size.minWidth, Math.min(_size.maxWidth, _uiStage.width));
//			_rect.height = Math.max(_size.minHeight, Math.min(_size.maxHeight, _uiStage.height));
//			var point:Point = layout(_rect, new Rectangle(0, 0, _uiStage.width, _uiStage.height), _size.horizontalAlign, _size.verticalAlign);
//			_rect.x = point.x;
//			_rect.y = point.y;
//			
//			trace (_rect + "" + _uiStage.x + "," + _uiStage.y + "," + _uiStage.width + "," + _uiStage.height);
//			
//			var container:UISprite;
//			var length:int = _containers.length;
//			for (var index:int = 0;index < length;index++)
//			{
//				container = _containers[index];
//				container.width = _rect.width;
//				container.height = _rect.height;
//				container.x = _rect.x;
//				container.y = _rect.y;
//			}
//		}
		private static function validateContainerDepth():void
		{
			_containers.sortOn("layer", Array.NUMERIC);
			var indexTop:int = _uiStage.numChildren - 1;
			var length:int = _containers.length;
			for (var index:int = 0;index < length;index++)
			{
				_uiStage.setChildIndex(_containers[index], indexTop);
			}
		}
//============================================================================
//HANDLER
//============================================================================
//		private static function stageResize_handler(event:Event):void
//		{
//			validateAppSize();
//		}
//		private static function sizeChanged_handler(event:Event):void
//		{
//			validateAppSize();
//		}
//============================================================================
//CALLBACK
//============================================================================
		private static function uiDelayed_cb(vo:TimerVO):void
		{
			delete _uidDelayTimerMap[UISprite(vo.data).uid];
			removeUI(vo.data as UISprite);
		}
//============================================================================
//GETTER/SETTER
//============================================================================
		public static function get uiStage():UIStage
		{
			return _uiStage;
		}
		public static function get stage():Stage
		{
			if (_uiStage == null) return null;
			return _uiStage.stage;
		}
		public static function get size():UISize
		{
			return _size;
		}
		public static function get rect():Rectangle
		{
			return _rect;
		}

	}
}